﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Validity.Test.Constraints
{
  [TestClass]
  public class IsNotInDomainConstraint
    : ConstraintTestBase<ObjectStub>
  {
    public class Validator
      : ValidatorBase<ObjectStub>
    {
      public Validator()
      {
        var domain = new List<Decimal> { 0m, 1, 2, 2, 3, 4, 5 };

        DefineRulesFor(ctx => ctx.MyDecimalProperty1).IsNotInDomain(0, 1, 2, 2, 3, 4, 5);
        DefineRulesFor(ctx => ctx.MyDecimalProperty2).IsNotInDomain(domain);
        DefineRulesFor(ctx => ctx.MyDecimalProperty2).IsNotInDomain(() => domain);
        DefineRulesFor(ctx => ctx.MyDecimalProperty3).IsNotInDomain(obj => domain);
      }
    }

    public IsNotInDomainConstraint() : base(new Validator(), 4) { }

    [TestMethod]
    public void TestConstraintVerified()
    {
      ValidateConstraintVerfied(CreateContext(-1));
      ValidateConstraintVerfied(CreateContext(6));
    }

    [TestMethod]
    public void TestConstraintViolated()
    {
      const String ruleViolation = "Must be a known value";

      ValidateConstraintViolated(CreateContext(0), ruleViolation);
      ValidateConstraintViolated(CreateContext(1), ruleViolation);
      ValidateConstraintViolated(CreateContext(2), ruleViolation);
      ValidateConstraintViolated(CreateContext(3), ruleViolation);
      ValidateConstraintViolated(CreateContext(4), ruleViolation);
      ValidateConstraintViolated(CreateContext(5), ruleViolation);
    }

    public ObjectStub CreateContext(Decimal value)
    {
      var result = new ObjectStub();

      result.MyDecimalProperty1 = value;
      result.MyDecimalProperty2 = value;
      result.MyDecimalProperty3 = value;

      return result;
    }
  }
}